import TileLayer from "ol/layer/Tile.js";
import XYZ from "ol/source/XYZ";
import WKT from "ol/format/WKT";
import GeoJSON from "ol/format/GeoJSON";
import { transform } from "ol/proj";
import { Map } from "ol";
import Polygon from "ol/geom/Polygon";
import MultiPolygon from "ol/geom/MultiPolygon";
import Feature from "ol/Feature";
import MultiPoint from "ol/geom/MultiPoint";
export default class MapUtils {
  mapEventFunArray;
  constructor(res) {}

  /**
   * 创建 xyz 图层
   * @param {*} config
   * @returns
   */
  createTiledXYZLayer(config) {
    const layer = new TileLayer({
      className: config.id || undefined,
      visible: config.visible,
    });
    const source = new XYZ({
      url: config["url"] || undefined,
      crossOrigin: "anonymous",
      wrapX: false,
      maxZoom: config["maxZoom"] || undefined,
      minZoom: config["minZoom"] || undefined,
    });
    layer.setSource(source);
    return layer;
  }

  /**
   * 添加一个地图事件
   * @param type 地图事件类型，包括：singleclick(单击)，dblclick(双击)，pointermove（地图鼠标移动），pointerdrag（鼠标拖拽）
   * @param listener 事件响应函数
   */
  addMapEvent(map, type, listener) {
    this.getFeature(map, listener);
    if (this.mapEventFunArray.length > 0) {
      let len = this.mapEventFunArray.length;
      for (let i = 0; i < len; i++) {
        if (this.mapEventFunArray[i].callback == listener) {
          map.on(type, this.mapEventFunArray[i].func);
        }
      }
    }
  }

  getFeature(map, callback) {
    this.mapEventFunArray
      ? this.mapEventFunArray
      : (this.mapEventFunArray = []);
    const that = this;
    let eventFun = function (event) {
      const pixel = event.pixel;
      const dataArr = [];
      if (event.type === "click") {
        let featureArray = [];
        let pointFeatureArray = [];
        let polygonFeatureArray = [];
        let regionFeature = undefined;
        map.forEachFeatureAtPixel(pixel, (feature) => {
          if (event.type === "click") {
            if (feature) {
              //捕捉到要素
              if (feature.getProperties().features) {
                //聚合情况下
                if (feature.getProperties().features.length == 1) {
                  //只有一个要素
                  feature = feature.getProperties().features[0]; //获取该要素
                  pointFeatureArray.push(feature);
                  // 聚合->单个要素
                } else {
                  // 聚合->多个要素
                  // clusterFlag = true
                  pointFeatureArray = pointFeatureArray.concat(
                    feature.getProperties().features
                  );
                }
              } else {
                //非聚合情况下
                let featureData = feature.getProperties()["data"];
                if (!featureData) return;
                // let featureType = featureData.data['type']
                // if (!featureType) return
                if (
                  feature.getGeometry() instanceof Polygon ||
                  feature.getGeometry() instanceof MultiPolygon
                ) {
                  polygonFeatureArray.push(feature);
                } else {
                  pointFeatureArray.push(feature);
                }

                // if (feature.getProperties()['data']) {
                //   // regionFeature = feature
                //   listener ? listener(feature.getProperties()) : console.log('没有回调函数');
                // }
              }
            }
          }
        });
        featureArray = pointFeatureArray.length
          ? pointFeatureArray
          : polygonFeatureArray.length
          ? polygonFeatureArray
          : [];
        if (event.type === "click") {
          if (featureArray.length > 1) {
            let sunPoint = 0;
            featureArray.forEach((featuredata) => {
              if (
                featuredata.getProperties().data &&
                featuredata.getProperties().data.data &&
                featuredata.getProperties().data.data.type === "sumPoint"
              ) {
                sunPoint = 1;
                let singleFeature = featuredata;
                // => 单个
                let eventData = {};
                eventData["position"] = event.coordinate;
                eventData["type"] = "click";
                eventData["target"] = map.getTargetElement();
                eventData["feature"] = singleFeature;
                eventData["data"] = singleFeature.get("data");
                dataArr.push(eventData);
                callback(dataArr[0]);
                return;
              }
            });
            if (sunPoint) return;
            // map.getView().getZoom() < map.getView().getMaxZoom() &&
            // featureArray[0].getProperties().data &&
            // featureArray[0].getProperties().data.data &&
            // featureArray[0].getProperties().data.data.type !== 'topic'
            if (
              map.getView().getZoom() < map.getView().getMaxZoom() &&
              featureArray[0].getProperties().data &&
              featureArray[0].getProperties().data.type !== "topic"
            ) {
              // 多个深入
              const f = new Feature();
              f.setProperties({
                features: featureArray,
              });
              that.selectStyleFunction(f, map);
              callback({
                position: event["position"],
                type: "singleclick",
                target: map.getTargetElement(),
              });
            } else {
              // => 多个 弹出选择
              // TODO: 多个弹窗的回调
              callback({
                position: event["coordinate"],
                type: "singleclick",
                target: map.getTargetElement(),
                infoWindow: true,
                dataList: featureArray.map((item) => item.get("data")),
              });
            }
          } else if (featureArray.length === 1) {
            let singleFeature = featureArray[0];
            // => 单个
            let eventData = {};
            if (pointFeatureArray.length) {
              eventData["position"] = singleFeature
                .getGeometry()
                .getCoordinates();
            } else {
              eventData["position"] = event.coordinate;
            }
            eventData["type"] = "click";
            eventData["target"] = map.getTargetElement();
            eventData["feature"] = singleFeature;
            eventData["data"] = singleFeature.get("data");
            dataArr.push(eventData);
            callback(dataArr[0]);
          } else if (regionFeature) {
            callback({
              regionFeature,
            });
          } else {
            callback({ event });
          }

          // console.log('featureArray', featureArray);
          // console.log('pointFeatureArray', pointFeatureArray);
          // console.log('polygonFeatureArray', polygonFeatureArray);
          // console.log('regionFeature', regionFeature);
        }
      }
    };
    this.mapEventFunArray.push({ callback: callback, func: eventFun });
    // listener ? listener(feature.getProperties()) : console.log('没有回调函数');
  }

  /**
   * 移除一个地图事件
   * @param type 地图事件类型，包括：singleclick(单击)，dblclick(双击)，pointermove（地图鼠标移动），pointerdrag（鼠标拖拽）
   * @param listener 事件响应函数
   */
  removeMapEvent(map, type, listener) {
    // map.un(type, listener)
    let funIndex;
    let len = this.mapEventFunArray.length;
    for (let i = 0; i < len; i++) {
      if (this.mapEventFunArray[i].callback == listener) {
        map.un(type, this.mapEventFunArray[i].func);
        funIndex = i;
      }
    }
    this.mapEventFunArray.splice(funIndex, 1);
  }

  //设置聚合图元选择中后处理
  selectStyleFunction(feature, map) {
    if (feature) {
      var originalFeatures = feature.get("features");
      if (originalFeatures.length <= 1) {
        return;
      }
      var multiPoints = new MultiPoint([]);
      for (var i = 0; i < originalFeatures.length; i++) {
        var point = originalFeatures[i].getGeometry();
        multiPoints.appendPoint(point);
      }

      var myView = map.getView();
      var size = map.getSize();
      var paddingSize = size[0] / 10;
      if (size[0] > size[1]) {
        paddingSize = size[1] / 10;
      }
      myView.fit(multiPoints, {
        size: map.getSize(),
        padding: [paddingSize, paddingSize, paddingSize, paddingSize],
        duration: 1500,
      });
    }
  }

  getWkt(wktArray) {
    return wktArray.map((data) => {
      if (data.indexOf("SRID=4326;") !== -1) {
        data = data.substring(10);
      }
      let wkt_c = new WKT();
      let geometry = wkt_c.readGeometry(data);
      let convertor = new GeoJSON();
      let geojson = JSON.parse(convertor.writeGeometry(geometry));
      let point3857 = transform(
        [geojson["coordinates"][0], geojson["coordinates"][1]],
        "EPSG:4326",
        "EPSG:3857"
      );
      return { x: point3857[0], y: point3857[1] };
    });
  }

  /**
   * @description 获取中心点
   * @param {*} data 4326字段的坐标
   * @returns {[Number,Number]} 3857[x,y] 的坐标
   */
   getFeatureCoordinate(data) {
    // 
    if (data.indexOf("SRID=4326;") !== -1) {
      data = data.substring(10);
    }

    let wkt_c = new WKT();
    let feature = wkt_c.readFeature(data, {
      dataProjection: "EPSG:4326",
      featureProjection: "EPSG:3857",
    });
    return ol.extent.getCenter(feature.getGeometry().getExtent());
  }
  /**
   * @description 获取中心点
   * @param {*} data 4326字段的坐标
   * @returns {[number,number,number,number]} 3857 的坐标
   */
   getFeatureExtent(data) {
    if (data.indexOf("SRID=4326;") !== -1) {
      data = data.substring(10);
    }

    let wkt_c = new WKT();
    let feature = wkt_c.readFeature(data, {
      dataProjection: "EPSG:4326",
      featureProjection: "EPSG:3857",
    });
    return feature.getGeometry().getExtent();
  }
   getWkts(wktArray) {
    return wktArray.map((data) => {
      if (data.indexOf("SRID=4326;") !== -1) {
        data = data.substring(10);
      }
      let wkt_c = new WKT();
      let geometry = wkt_c.readGeometry(data);
      let convertor = new GeoJSON();
      let geojson = JSON.parse(convertor.writeGeometry(geometry));
      let point3857 = transform(
        [geojson["coordinates"][0], geojson["coordinates"][1]],
        "EPSG:4326",
        "EPSG:3857"
      );
      return [point3857[0], point3857[1]];
    });
  }

  // 3857转4326  1253.152 ---> 113 [[xxx,yyy]] ---> [[xxx,yyy]]
   get4326(wktArray) {
    return wktArray.map((data) => {
      let point4326 = transform([data[0], data[1]], "EPSG:3857", "EPSG:4326");
      return [point4326[0], point4326[1]];
    });
  }

  // 3857转4326  11.3 -->1253.152   [[xxx,yyy]] --->  [[x:xxx,y:yyy]]
   getWkt4326(wktArray) {
    return wktArray.map((data) => {
      if (data.indexOf("SRID=4326;") !== -1) {
        data = data.substring(10);
      }
      let wkt_c = new WKT();
      let geometry = wkt_c.readGeometry(data);
      let convertor = new GeoJSON();
      let geojson = JSON.parse(convertor.writeGeometry(geometry));
      // let point3857 =transform(
      //   [geojson['coordinates'][0], geojson['coordinates'][1]],
      //   'EPSG:4326',
      //   'EPSG:3857'
      // )
      // let point3857 =transform(
      //   [data[0], data[1]],
      //   'EPSG:3857',
      //   'EPSG:4326'
      // )
      return { x: geojson["coordinates"][0], y: geojson["coordinates"][1] };
    });
  }
   getWkt3857(wktArray) {
    return wktArray.map((data) => {
      if (data.indexOf("SRID=4326;") !== -1) {
        data = data.substring(10);
      }
      let wkt_c = new WKT();
      let geometry = wkt_c.readGeometry(data);
      let convertor = new GeoJSON();
      let geojson = JSON.parse(convertor.writeGeometry(geometry));
      return { x: geojson["coordinates"][0], y: geojson["coordinates"][1] };
    });
  }

  /**
   * @description 返回多面
   * @
   */
   getArrayMultiPolygon(data) {
    if (data.indexOf("SRID=4326;") !== -1) {
      data = data.substring(10);
    }
    let wkt_c = new WKT();
    let feature = wkt_c.readFeature(data, {
      dataProjection: "EPSG:4326",
      featureProjection: "EPSG:3857",
    });
    return feature;
  }

  /**
   *
   * @param {*} wktArray
   * @param {*} isresove
   * @param {*} is3857 是否是3857
   * @returns
   */
  getMULTIPOLYGON(wktArray, isresove, is3857) {
    return wktArray.map((data) => {
      if (data.indexOf("SRID=4326;") !== -1) {
        data = data.substring(10);
      }
      let wkt_c = new WKT();
      let geometry = wkt_c.readFeatures(data);
      let convertor = new GeoJSON();
      let geojson = JSON.parse(convertor.writeFeatures(geometry));
      if (isresove) {
        // 不需要转码  只需要过滤
        if (is3857) {
          return geojson.features[0].geometry.coordinates[0][0].map(
            (multip) => {
              return [multip[0], multip[1]];
            }
          );
        }
        return this.resovePointList(
          geojson.features[0].geometry.coordinates[0][0]
        );
      } else {
        return this.convertPointsDataToArray(
          geojson.features[0].geometry.coordinates[0][0]
        );
      }
    });
  }
  // 数据处理，将数据转换为[x:x,y:y]数组构建形式
   convertPointsDataToArray(geometry) {
    // let pointsArray: any = []
    return geometry.map((value) => {
      let point3857 = transform([value[0], value[1]], "EPSG:4326", "EPSG:3857");
      return { x: point3857[0], y: point3857[1] };
    });
  }

  /**
   * @description 解析map Extent 4326>3857  (113.11>123456.11)
   * @param {*} xMin
   * @param {*} yMin
   * @param {*} xMax
   * @param {*} yMax
   * @returns {[number, number, number, number]}
   */
   resoveExtent(xMin, yMin, xMax, yMax) {
    let extentone = transform(
      [Number(xMin), Number(yMin)],
      "EPSG:4326",
      "EPSG:3857"
    );
    let extenttwo = transform(
      [Number(xMax), Number(yMax)],
      "EPSG:4326",
      "EPSG:3857"
    );
    return [extentone[0], extentone[1], extenttwo[0], extenttwo[1]];
  }

  // 数据处理，将数据转换为[xxxx,yyy]数组构建形式  用于查询面的中心点
   resovePointList(geometry) {
    // let pointsArray: any = []
    return geometry.map((value) => {
      let point3857 = transform([value[0], value[1]], "EPSG:4326", "EPSG:3857");
      return [point3857[0], point3857[1]];
    });

    // return pointsArray
  }

  // 检测坐标xxx,xxxx
   detectionCoordinate(coordinate, messageservice) {
    let geometry = null;
    if (coordinate) {
      let index = coordinate.indexOf(",");
      let x = "";
      let y = "";
      if (index) {
        x = coordinate.substring(0, index);
        y = coordinate.substring(index + 1);
        if (x && y) {
          geometry = "POINT(" + x + " " + y + ")";
        } else {
          messageservice.create(
            "error",
            "输入错误，请输入(xxx,xxxx)格式的经纬度!"
          );
        }
      } else {
        messageservice.create(
          "error",
          "输入错误，请输入(xxx,xxxx)格式的经纬度!"
        );
      }
    } else {
      // 默认坐标
      geometry = "POINT(113.35006177425386 23.143299918304635)";
    }
    return geometry;
  }

  //[] => []
   get4326Point(coordinate) {
    returntransform(coordinate, "EPSG:3857", "EPSG:4326");
  }
}
